home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / ATTRIB.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  12KB  |  510 lines

  1. /*    SCCS Id: @(#)attrib.c    3.0    90/2/15
  2. /*    Copyright 1988, 1989, 1990, M. Stephenson          */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /*  attribute modification routines. */
  6.  
  7. #include "hack.h"
  8.  
  9. #ifdef OVLB
  10.  
  11. const char    *plusattr[] = {    /* part of the output on gain of attribute */
  12.  
  13.     "strong", "smart", "wise", "agile", "tough", "charismatic"
  14. };
  15.  
  16. const char    *minusattr[] = { /* part of the output on loss of attribute */
  17.  
  18.     "weak", "stupid", "foolish", "clumsy", "vulnerable", "ugly"
  19. };
  20.  
  21. struct attribs    attrmax = {    /* max values for the attributes */
  22.  
  23.     118, 18, 18, 18, 18, 18
  24. },
  25.         attrmin = {    /* min values for the attributes */
  26.  
  27.     3, 3, 3, 3, 3, 3
  28. };
  29.  
  30. const struct innate {
  31.  
  32.     schar    ulevel;
  33.     long    *ability;
  34.     const char *gainstr, *losestr;
  35. }    a_abil[] = { {     1, &(Stealth), "", "" },
  36.              {   1, &(Fast), "", "" },
  37.              {  10, &(Searching), "perceptive", "" },
  38.              {     0, 0, 0, 0 } },
  39.  
  40.     b_abil[] = { {     1, &(HPoison_resistance), "", "" },
  41.              {   7, &(Fast), "quick", "slow" },
  42.              {  15, &(Stealth), "stealthy", "" },
  43.              {     0, 0, 0, 0 } },
  44.  
  45.     c_abil[] = { {     7, &(Fast), "quick", "slow" },
  46.              {    15, &(Warning), "sensitive", "" },
  47.              {     0, 0, 0, 0 } },
  48.  
  49.     e_abil[] = { {   1, &(Fast), "", "" },
  50.              {     1, &(HSee_invisible), "", "" },
  51.              {     1, &(Searching), "", "" },
  52.              {     1, &(HSleep_resistance), "", "" },
  53.              {     0, 0, 0, 0 } },
  54.  
  55.     h_abil[] = { {     1, &(HPoison_resistance), "", "" },
  56.              {    15, &(Warning), "sensitive", "" },
  57.              {     0, 0, 0, 0 } },
  58.  
  59.     k_abil[] = { {     7, &(Fast), "quick", "slow" },
  60.              {     0, 0, 0, 0 } },
  61.  
  62.     p_abil[] = { {    15, &(Warning), "sensitive", "" },
  63.              {  20, &(HFire_resistance), "cool", "warmer" },
  64.              {     0, 0, 0, 0 } },
  65.  
  66.     r_abil[] = { {     1, &(Stealth), "", ""  },
  67.              {  10, &(Searching), "perceptive", "" },
  68.              {     0, 0, 0, 0 } },
  69.  
  70.     s_abil[] = { {     1, &(Fast), "", "" },
  71.              {  15, &(Stealth), "stealthy", "" },
  72.              {     0, 0, 0, 0 } },
  73.  
  74.     t_abil[] = { {    10, &(Searching), "perceptive", "" },
  75.              {    20, &(HPoison_resistance), "hardy", "" },
  76.              {     0, 0, 0, 0 } },
  77.  
  78.     v_abil[] = { {     1, &(HCold_resistance), "", "" },
  79.              {     1, &(Stealth), "", "" },
  80.              {   7, &(Fast), "quick", "slow" },
  81.              {     0, 0, 0, 0 } },
  82.  
  83.     w_abil[] = { {    15, &(Warning), "sensitive", "" },
  84.              {  17, &(HTeleport_control), "controlled","uncontrolled" },
  85.              {     0, 0, 0, 0 } };
  86.  
  87. const struct clattr {
  88.  
  89.     struct    attribs    base, dist;
  90.      schar    align, aligntyp;
  91.     schar    shp, hd, xlev, ndx;
  92. /* According to AD&D, HD for some classes (ex. Wizard) should be smaller
  93.  * (4-sided for wizards).  But this is not AD&D, and using the AD&D
  94.  * rule here produces an unplayable character.  This I have used a minimum
  95.  * of an 10-sided hit die for everything.  Another AD&D change: wizards get
  96.  * a minimum strength of 6 since without one you can't teleport or cast
  97.  * spells. --KAA
  98.  */
  99.     const struct    innate *abil;
  100. }    a_attr = { {     7, 10, 10,  7,  7,  7 },  /* Archeologist */
  101.            {    20, 20, 20, 10, 20, 10 },
  102.             10,  1, 13, 10, 14,  2, a_abil },
  103.  
  104.     b_attr = { {    16,  7,  7, 15, 16,  6 },  /* Barbarian */
  105.            {    30,  6,  7, 20, 30,  7 },
  106.             10, -1, 16, 12, 10,  3, b_abil },
  107.  
  108.     c_attr = { {    10,  7,  7,  7,  8,  6 },  /* Caveman (fighter) */
  109.            {    30,  6,  7, 20, 30,  7 },
  110.              0,  1, 16, 10, 10,  3, c_abil },
  111.  
  112. /*
  113.     e_attr = { {    13, 13, 14,  6, 14,  6 },
  114.  */
  115.     e_attr = { {    13, 13, 13,  9, 13,  7 },  /* Elf (ranger) */
  116.            {    30, 10, 10, 20, 20, 10 },
  117.             10,  1, 15, 10, 11,  2, e_abil },
  118.  
  119.     h_attr = { {     7,  7, 13,  7, 11, 16 },  /* Healer (druid) */
  120.            {    15, 20, 20, 15, 25, 10 },
  121.             10,  1, 13, 10, 20,  2, h_abil },
  122.  
  123.     k_attr = { {    13,  7, 14,  8, 10, 17 },  /* Knight (paladin) */
  124.            {    20, 15, 15, 10, 20, 10 },
  125.             10,  1, 16, 10, 10,  3, k_abil },
  126.  
  127.     p_attr = { {     7,  7, 10,  7,  7,  7 },  /* Priest (cleric) */
  128.            {    15, 10, 30, 15, 20, 10 },
  129.              0,  0, 14, 10, 10,  2, p_abil },
  130.  
  131.     r_attr = { {     7,  7,  7, 10,  7,  6 },  /* Rogue (thief) */
  132.            {    20, 10, 10, 30, 20, 10 },
  133.             10, -1, 12, 10, 11,  2, r_abil },
  134.  
  135.     s_attr = { {    10,  8,  7, 10, 17,  6 },  /* Samurai (fighter/thief) */
  136.            {    30, 10, 10, 30, 14, 10 },
  137.             10,  1, 15, 10, 11,  2, s_abil },
  138.  
  139.     t_attr = { {     7, 10,  6,  7,  7, 10 },  /* Tourist */
  140.            {    15, 10, 10, 15, 30, 20 },
  141.              0,  0, 10, 10, 14,  1, t_abil },
  142.  
  143.     v_attr = { {    10,  7,  7,  7, 10,  7 },  /* Valkyrie (fighter) */
  144.            {    30,  6,  7, 20, 30,  7 },
  145.              0, -1, 16, 10, 10,  3, v_abil },
  146.  
  147.     w_attr = { {     7, 10,  7,  7,  7,  7 },  /* Wizard (magic-user) */
  148.            {    10, 30, 10, 20, 20, 10 },
  149.              0,  0, 12, 10, 12,  1, w_abil },
  150.  
  151.     X_attr = { {     3,  3,  3,  3,  3,  3 },
  152.            {    20, 15, 15, 15, 20, 15 },
  153.              0,  0, 12, 10, 14,  1,  0 };
  154.  
  155. static const struct clattr NEARDATA *NDECL(clx);
  156. static void NDECL(init_align);
  157.  
  158. void
  159. adjattrib(ndx, incr, silent)
  160.  
  161.     int    ndx, incr;
  162.     boolean    silent;
  163. {
  164.     if(!incr) return;
  165.  
  166.     if(incr > 0) {
  167.         if((AMAX(ndx) >= attrmax.a[ndx]) && (ACURR(ndx) >= AMAX(ndx))) {
  168.  
  169.         if(!silent && flags.verbose)
  170.             pline("You're already as %s as you can get.",
  171.               plusattr[ndx]);
  172.         ABASE(ndx) = AMAX(ndx) = attrmax.a[ndx]; /* just in case */
  173.         return;
  174.         }
  175.  
  176.         ABASE(ndx) += incr;
  177.         if(ABASE(ndx) > AMAX(ndx)) {
  178.         incr = ABASE(ndx) - AMAX(ndx);
  179.         AMAX(ndx) += incr;
  180.         if(AMAX(ndx) > attrmax.a[ndx])
  181.             AMAX(ndx) = attrmax.a[ndx];
  182.         ABASE(ndx) = AMAX(ndx);
  183.         }
  184.     } else {
  185.         if((AMAX(ndx) <= attrmin.a[ndx]) && (ABASE(ndx) == AMAX(ndx))) {
  186.         if(!silent && flags.verbose)
  187.             pline("You're already as %s as you can get.",
  188.               minusattr[ndx]);
  189.         ABASE(ndx) = AMAX(ndx) = attrmin.a[ndx]; /* just in case */
  190.         return;
  191.         }
  192.  
  193.         ABASE(ndx) += incr;
  194.         if(ABASE(ndx) < attrmin.a[ndx]) {
  195.         incr = ABASE(ndx) - attrmin.a[ndx];
  196.         ABASE(ndx) = attrmin.a[ndx];
  197.         AMAX(ndx) += incr;
  198.         if(AMAX(ndx) < attrmin.a[ndx])
  199.             AMAX(ndx) = attrmin.a[ndx];
  200.         }
  201.     }
  202.     if(!silent)
  203.         You("feel %s%s!",
  204.           (incr > 1) ? "very ": "",
  205.           (incr > 0) ? plusattr[ndx] : minusattr[ndx]);
  206.     flags.botl = 1;
  207.     return;
  208. }
  209.  
  210. void
  211. gainstr(otmp, incr)
  212.     register struct obj *otmp;
  213.     register int incr;
  214. {
  215.     int num = 1;
  216.  
  217.     if(incr) num = incr;
  218.     else {
  219.         if(ABASE(A_STR) < 18) num = (rn2(4) ? 1 : rnd(6) );
  220.         else if (ABASE(A_STR) < 103) num = rnd(10);
  221.     }
  222.     adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num, TRUE);
  223. }
  224.  
  225. void
  226. losestr(num)    /* may kill you; cause may be poison or monster like 'a' */
  227.     register int num;
  228. {
  229.     int ustr = ABASE(A_STR) - num;
  230.  
  231.     while(ustr < 3) {
  232.         ustr++;
  233.         num--;
  234.         u.uhp -= 6;
  235.         u.uhpmax -= 6;
  236.     }
  237.     adjattrib(A_STR, -num, TRUE);
  238. }
  239.  
  240. void
  241. change_luck(n)
  242.     register schar n;
  243. {
  244.     u.uluck += n;
  245.     if (u.uluck < 0 && u.uluck < LUCKMIN)    u.uluck = LUCKMIN;
  246.     if (u.uluck > 0 && u.uluck > LUCKMAX)    u.uluck = LUCKMAX;
  247. }
  248.  
  249. int
  250. stone_luck(parameter)
  251. boolean parameter; /* So I can't think up of a good name.  So sue me. --KAA */
  252. {
  253.     register struct obj *otmp;
  254.     register int bonchance = 0;
  255.  
  256.     for(otmp = invent; otmp; otmp=otmp->nobj)
  257.         if(otmp->otyp == LUCKSTONE) {
  258.         if (otmp->cursed) bonchance -= (int)otmp->quan;
  259.         else if (otmp->blessed) bonchance += otmp->quan;
  260.         else if (parameter) bonchance += otmp->quan;
  261.         }
  262.  
  263.     return sgn(bonchance);
  264. }
  265.  
  266. #endif /* OVLB */
  267. #ifdef OVL1
  268.  
  269. void
  270. restore_attrib() {
  271.  
  272.     int    i;
  273.  
  274.     for(i = 0; i < A_MAX; i++) {    /* all temporary losses/gains */
  275.  
  276.        if(ATEMP(i) && ATIME(i)) {
  277.         if(!(--(ATIME(i)))) { /* countdown for change */
  278.             ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;
  279.  
  280.             if(ATEMP(i)) /* reset timer */
  281.             ATIME(i) = 100 / ACURR(A_CON);
  282.         }
  283.         }
  284.     }
  285. }
  286.  
  287. #endif /* OVL1 */
  288. #ifdef OVLB
  289.  
  290. static const struct    clattr *
  291. clx()  {
  292.  
  293.     register const struct    clattr    *attr;
  294.  
  295.     switch    (pl_character[0]) {
  296.  
  297.         case 'A':    attr = &a_attr;
  298.             break;
  299.         case 'B':    attr = &b_attr;
  300.             break;
  301.         case 'C':    attr = &c_attr;
  302.             break;
  303.         case 'E':    attr = &e_attr;
  304.             break;
  305.         case 'H':    attr = &h_attr;
  306.             break;
  307.         case 'K':    attr = &k_attr;
  308.             break;
  309.         case 'P':    attr = &p_attr;
  310.             break;
  311.         case 'R':    attr = &r_attr;
  312.             break;
  313.         case 'S':    attr = &s_attr;
  314.             break;
  315.         case 'T':    attr = &t_attr;
  316.             break;
  317.         case 'V':    attr = &v_attr;
  318.             break;
  319.         case 'W':    attr = &w_attr;
  320.             break;
  321.         default:    /* unknown type */
  322.             attr = &X_attr;
  323.             break;
  324.     }
  325.     return(attr);
  326. }
  327.  
  328. static void
  329. init_align() {    /* called from newhp if u.ulevel is 0 */
  330.  
  331.     register const struct    clattr    *attr = clx();
  332.  
  333.     u.ualign = (int)attr->align;
  334.     u.ualigntyp = attr->aligntyp;
  335. }
  336.  
  337. void
  338. init_attr(np)
  339.     register int    np;
  340. {
  341.     register int    i, x, tryct;
  342.     register const struct    clattr    *attr = clx();
  343.  
  344.     for(i = 0; i < A_MAX; i++) {
  345.  
  346.         ABASE(i) = AMAX(i) = attr->base.a[i];
  347.         ATEMP(i) = ATIME(i) = 0;
  348.         np -= attr->base.a[i];
  349.     }
  350.  
  351.     tryct = 0;
  352.     while(np > 0 && tryct < 100) {
  353.  
  354.         x = rn2(100);
  355.         for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++);
  356.         if(i >= A_MAX) continue; /* impossible */
  357.  
  358.         if(ABASE(i) >= attrmax.a[i]) {
  359.  
  360.         tryct++;
  361.         continue;
  362.         }
  363.         tryct = 0;
  364.         ABASE(i)++;
  365.         AMAX(i)++;
  366.         np--;
  367.     }
  368.  
  369.     tryct = 0;
  370.     while(np < 0 && tryct < 100) {        /* for redistribution */
  371.  
  372.         x = rn2(100);
  373.         for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++);
  374.         if(i >= A_MAX) continue; /* impossible */
  375.  
  376.         if(ABASE(i) <= attrmin.a[i]) {
  377.  
  378.         tryct++;
  379.         continue;
  380.         }
  381.         tryct = 0;
  382.         ABASE(i)--;
  383.         AMAX(i)--;
  384.         np++;
  385.     }
  386. }
  387.  
  388. void
  389. redist_attr() {
  390.  
  391.     register int i, tmp;
  392.  
  393.     for(i = 0; i < A_MAX; i++) {
  394.         if (i==A_INT || i==A_WIS) continue;
  395.         /* Polymorphing doesn't change your mind */
  396.         tmp = AMAX(i);
  397.         AMAX(i) += (rn2(5)-2);
  398.         if (AMAX(i) > attrmax.a[i]) AMAX(i) = attrmax.a[i];
  399.         if (AMAX(i) < attrmin.a[i]) AMAX(i) = attrmin.a[i];
  400.         ABASE(i) = ABASE(i) * AMAX(i) / tmp;
  401.         /* ABASE(i) > attrmax.a[i] is impossible */
  402.         if (ABASE(i) < attrmin.a[i]) ABASE(i) = attrmin.a[i];
  403.     }
  404. }
  405.  
  406. void
  407. adjabil(oldlevel,newlevel)
  408. int oldlevel, newlevel;
  409. {
  410.     register const struct clattr    *attr = clx();
  411. #ifdef __GNULINT__
  412.     /* this is the "right" definition */
  413.     register const struct innate    *abil = attr->abil;
  414. #else
  415.     /* this one satisfies more compilers */
  416.     register struct innate    *abil = (struct innate *)attr->abil;
  417. #endif
  418.  
  419.     if(abil) {
  420.         for(; abil->ability; abil++) {
  421.         if(oldlevel < abil->ulevel && newlevel >= abil->ulevel) {
  422.             if(!(*(abil->ability) & INTRINSIC)) {
  423.                 *(abil->ability) |= INTRINSIC;
  424.                 if(strlen(abil->gainstr))
  425.                 You("feel %s!", abil->gainstr);
  426.             }
  427.         } else if (oldlevel >= abil->ulevel && newlevel < abil->ulevel) {
  428.             if((*(abil->ability) & INTRINSIC)) {
  429.                 *(abil->ability) &= ~INTRINSIC;
  430.                 if(strlen(abil->losestr))
  431.                 You("feel %s!", abil->losestr);
  432.                 else if(strlen(abil->gainstr))
  433.                 You("feel less %s!", abil->gainstr);
  434.             }
  435.         }
  436.         }
  437.     }
  438. }
  439.  
  440. int
  441. newhp() {
  442.     register const struct clattr    *attr = clx();
  443.     int    hp, conplus;
  444.  
  445.     if(u.ulevel == 0) {
  446.  
  447.         hp = attr->shp;
  448.         init_align();    /* initialize alignment stuff */
  449.         return hp;
  450.     } else {
  451.  
  452.         if(u.ulevel < attr->xlev)
  453.         hp = rnd(attr->hd);
  454.         else
  455.         hp = attr->ndx;
  456.     }
  457.  
  458.     switch(ACURR(A_CON)) {
  459.         case    3:    conplus = -2; break;
  460.         case    4:
  461.         case    5:
  462.         case    6:    conplus = -1; break;
  463.         case    15:
  464.         case    16:    conplus = 1; break;
  465.         case    17:    conplus = 2; break;
  466.         case    18:    conplus = 3; break;
  467.         default:    conplus = 0;
  468.     }
  469.     hp += conplus;
  470.     return((hp <= 0) ? 1 : hp);
  471. }
  472.  
  473. #endif /* OVLB */
  474. #ifdef OVL0
  475.  
  476. schar
  477. acurr(x)
  478. int x;
  479.     register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]);
  480.  
  481.     if (x == A_STR) {
  482.         if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) return(125);
  483.         else return((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp);
  484.     } 
  485.     else return((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp);
  486. }
  487.  
  488. #endif /* OVL0 */
  489. #ifdef OVL2
  490.  
  491. /* avoid possible problems with alignment overflow, and provide a centralized
  492.  * location for any future alignment limits
  493.  */
  494. void
  495. adjalign(n)
  496. register int n;
  497. {
  498.     register int newalign = u.ualign + n;
  499.  
  500.     if(n < 0) {
  501.         if(newalign < u.ualign)
  502.             u.ualign = newalign;
  503.     } else
  504.         if(newalign > u.ualign)
  505.             u.ualign = newalign;
  506. }
  507.  
  508. #endif /* OVL2 */
  509.